/* ==================================================================== */
/* This File Exclaims All the Double Link Node/List Operation Functions */
/*                   And Also The Structs and MACROs                    */
/* ==================================================================== */

#include "dl_event.h"

DL_EVENT_Q *p_dl_event_q = NULL;

void process_dl_events(void)
{
	DL_EVENT_T *p_cur_event = NULL;

	p_cur_event = get_dl_event();

	// if no valid event is got, return
	while(p_cur_event)
	{
		switch(p_cur_event->event_code)
		{
			case UNEXPECT_NULL_LIST:
			{
				printf("Process dl event UNEXPECT_NULL_LIST\r\n");
				p_list_test = create_an_empty_dl_list();
				break;
			}

			case NODE_NOT_FOUND:
			{
				int c_user_input = 0;
				printf("Process dl event NODE_NOT_FOUND\r\n");
				printf("dl node %d not found, create it now?\r\n",p_cur_event->data);
				printf("type '1' to create, others to exist\r\n");

				scanf("%d",&c_user_input);

				if(c_user_input)
				{
					printf("You have determined to create a new dl node with data %d\r\n",p_cur_event->data);
					if(insert_dl_node_to_tail(p_list_test,p_cur_event->data))
					{
						printf("Create Fail\r\n");
					}
					printf("Create Success\r\n");
					break;
				}
				printf("You have determined to exist directly\r\n");
				break;
			}

			default:
			{
				break;
			}
		}

		free_dl_event(p_cur_event);
		p_cur_event = get_dl_event();
	}
}

DL_EVENT_T *malloc_dl_event(void)
{
	DL_EVENT_T *new_event = NULL;

	new_event = (DL_EVENT_T *)malloc(sizeof(DL_EVENT_T));
	
	if(NULL == new_event)
	{
		printf("Fail to create new event due to malloc fail!\r\n");
		return NULL;
	}

	memset(new_event, 0 ,sizeof(DL_EVENT_T));
	
	return new_event;	
}

int post_dl_event(DL_EVENT_CODE e_code, int data)
{
	DL_EVENT_T *p_cur_event = NULL;

	p_cur_event = malloc_dl_event();
	
	// if fail to create an empty event
	if(NULL == p_cur_event)
	{
		return -1;
	}

	// update the dl_event_q
	if(NULL == p_dl_event_q)
	{
		printf("Fail to post new event due to NULL dl_event_q!\r\n");
		return -1;
	}

	p_cur_event->event_code = e_code;
	p_cur_event->data = data;

	// if the event queue is empty, add it to the head
	if(NULL == p_dl_event_q->p_event_head)
	{
		p_dl_event_q->p_event_head = p_cur_event;
		p_dl_event_q->p_event_tail = p_cur_event;
		p_dl_event_q->event_count = 1;
	}
	// else, add it to the tail
	else
	{
		(p_dl_event_q->p_event_tail)->p_next_event = p_cur_event;
		p_cur_event->p_prev_event = p_dl_event_q->p_event_tail;
		p_dl_event_q->p_event_tail = p_cur_event;
		p_dl_event_q->event_count++;
	}

	return 0;
}

int free_dl_event(DL_EVENT_T *p_dl_event)
{
	// check if this event is valid
	if((NULL == p_dl_event) || (NULL == p_dl_event_q))
	{
		printf("Event is not valid!\r\n");
	}
	// check if this event is the only one 
	else if(p_dl_event->p_next_event)
	{
		// not the only one, remove it from the head
		(p_dl_event->p_next_event)->p_prev_event = NULL;
		p_dl_event_q->p_event_head = p_dl_event->p_next_event;
		p_dl_event_q->event_count--;
	}
	else
	{
		p_dl_event_q->p_event_head = NULL;
		p_dl_event_q->p_event_tail = NULL;
		p_dl_event_q->event_count = 0;
	}

	if(p_dl_event)
	{
		free(p_dl_event);
	}
	return 0;
}

DL_EVENT_T *get_dl_event(void)
{
	// if no valid event exists
	if(NULL == p_dl_event_q || 0 == p_dl_event_q->event_count)
	{
		return NULL;
	}

	// else return the first one
	return p_dl_event_q->p_event_head;
}
